package com.niiwoo.civet.mobile.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.dto.response.WithholdProtocolResultDTO;
import com.niiwoo.civet.account.service.withholdProtocol.WithholdProtocolDubboService;
import com.niiwoo.civet.base.constant.OrgConstant;
import com.niiwoo.civet.mobile.util.R360RedisService;
import com.niiwoo.civet.mobile.vo.request.userBiz.UserBizOperateRequestVO;
import com.niiwoo.civet.mobile.vo.response.userBiz.UserBizOperateResponseVO;
import com.niiwoo.civet.trade.dto.response.myloan.ImmediateRepaymentResponseDTO;
import com.niiwoo.civet.trade.dto.response.newRefund.OrgImmediateRepaymentResponseDTO;
import com.niiwoo.civet.trade.service.myloan.MyLoanDubboService;
import com.niiwoo.civet.user.service.OrganizationDubboService;
import com.niiwoo.tripod.web.annotation.AuthIgnore;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
 * User business operate
 *
 * @author xiaoyaocai
 */
@RestController
@RequestMapping("/userBiz/operate")
@Api(tags = "业务操作", description = "/userBiz/operate")
@Slf4j
public class UserBizOperateController {

    @Autowired
    private R360RedisService r360RedisService;
    @Reference(version = "1.0.0")
    private OrganizationDubboService organizationDubboService;
    @Reference(version = "1.0.0")
    private WithholdProtocolDubboService withholdProtocolDubboService;
    @Reference(version = "1.0.0")
    private MyLoanDubboService myLoanDubboService;

    @PostMapping("/getUserBiz")
    @ApiOperation(value = "获取用户业务操作数据", notes = "如果 currentPayment & currentPeriodId 为空，则显示当前用户无还款任务")
    @AuthIgnore
    public Result<UserBizOperateResponseVO> getUserBiz(@RequestBody @Valid UserBizOperateRequestVO requestVO){
        UserBizOperateResponseVO responseVO = new UserBizOperateResponseVO();
        String userId = validThirdToken(requestVO.getToken(), requestVO.getChannel());
        String orgId = getOrgId(requestVO.getChannel(), requestVO.getOrgCode());

        WithholdProtocolResultDTO withholdProtocolResultDTO = withholdProtocolDubboService.getWithholdProtocolResultForLocal(userId, orgId);
        if (Boolean.TRUE.equals(withholdProtocolResultDTO.getResult()) && withholdProtocolResultDTO.getExpire() == 1) {
            responseVO.setSignStatus(1); // 已开通代扣
        } else {
            if (Boolean.TRUE.equals(withholdProtocolResultDTO.getResult()) && withholdProtocolResultDTO.getExpire() == 0) {
                responseVO.setSignStatus(2); // 已失效
            } else {
                responseVO.setSignStatus(0); // 未开通代扣
            }
        }

        OrgImmediateRepaymentResponseDTO orgImmediateRepaymentResponseDTO = myLoanDubboService.queryOrgImmediateRepayment(userId,orgId);
        if( Objects.nonNull(orgImmediateRepaymentResponseDTO) ){
            if( orgImmediateRepaymentResponseDTO.getStatus().equals((byte)3)){
                log.info("用户已还清：{}",userId);
                return Result.with(responseVO);
            }else if( orgImmediateRepaymentResponseDTO.getStatus().equals((byte)0) || orgImmediateRepaymentResponseDTO.getStatus().equals((byte)1)){
                if( Objects.nonNull(orgImmediateRepaymentResponseDTO.getAmount()) && orgImmediateRepaymentResponseDTO.getAmount().compareTo(new BigDecimal(0)) != 0){
                    responseVO.setCurrentPayment("本期应还"+orgImmediateRepaymentResponseDTO.getAmount()+"元");
                    log.info("用户:{}当前需还款：{}", userId,JSON.toJSONString(responseVO));
                }
            }else if(orgImmediateRepaymentResponseDTO.getStatus().equals((byte)4)){
                if( Objects.nonNull(orgImmediateRepaymentResponseDTO.getNextPeriodAmount()) && orgImmediateRepaymentResponseDTO.getNextPeriodAmount().compareTo(new BigDecimal(0)) != 0){
                    responseVO.setCurrentPayment("下期应还"+orgImmediateRepaymentResponseDTO.getNextPeriodAmount()+"元");
                    log.info("用户:{}下期需还款：{}", userId,JSON.toJSONString(responseVO));
                }
                log.info("用户：{}下期需还款：{}",userId,JSON.toJSONString(responseVO));
            }else if( orgImmediateRepaymentResponseDTO.getStatus().equals((byte)2)){
                log.info("用户：{}还没有到还款这一步",userId);
            }else{
                log.error("结果状态不在注册列表");
            }
        }

        return Result.with(responseVO);
    }

    /**
     * 验证第三方TOKEN，获取userId
     * @param token token valid user information
     * @param channel channel transform
     * @return userId
     */
    private String validThirdToken(String token, Integer channel) {
        String userId;
        if (channel == null) {
            userId = r360RedisService.verifyTokenAndGetUserId(token);
        } else {
            userId = r360RedisService.verifyTokenAndGetUserId(token, channel);
        }
        return userId;
    }

    /**
     * get orgId
     * @param channel channel transform
     * @param orgCode org code
     * @return orgId
     */
    private String getOrgId(Integer channel, String orgCode) {
        String orgId = OrgConstant.NIIWOO_ORG_ID;
        if (Objects.equals(R360RedisService.ThirdPart.ORG.getChannel(), channel)) {
            orgId = organizationDubboService.loadValidOrgId(orgCode);
        }
        return orgId;
    }

    @PostMapping("/checkUserWithholdProtocolSigned")
    @ApiOperation(value = "用户签约数据校验")
    @AuthIgnore
    public String checkUserWithholdProtocolSigned(){
        RpcContext.getContext().asyncCall(() -> withholdProtocolDubboService.checkUserWithholdProtocolSigned());
        String result = "服务已启动";
        return result;
    }
}
